package dr.common;

import cn.hutool.core.util.StrUtil;
import dr.common.i18n.ResKit;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Getter
@Setter
@NoArgsConstructor
@SuppressWarnings("unchecked")
public final class ResultModel extends HashMap<String, Object> {

    private static final String MSG_SUCCESS_CONSTANT = "成功";
    private static final String MSG_FAILED_CONSTANT = "失败";

    private static final String ERROR_CODE = "errorCode";
    private static final String DATA = "data";
    private static final String MSG = "msg";

    private static final int SUCCESS_STATUS = 1;
    private static final int FAILED_STATUS = -100;//默认就是要弹窗的
    private static final int EXCEPTION_STATUS = -101;//默认就是要弹窗的


    public static ResultModel ok() {
        return new ResultModel(ResKit.getMsg("op_ok"), SUCCESS_STATUS, null);
    }

    public static ResultModel err() {
        return new ResultModel(ResKit.getMsg("op_err"), FAILED_STATUS, null);
    }

    public static ResultModel success(String msg) {
        return new ResultModel(msg, SUCCESS_STATUS, null);
    }


    public static ResultModel success(Object data) {
        return new ResultModel(MSG_SUCCESS_CONSTANT, SUCCESS_STATUS, data);
    }

    public static ResultModel success(String msg, Object data) {
        return new ResultModel(msg, SUCCESS_STATUS, data);
    }

    public static ResultModel fail(String msg) {
        return new ResultModel(msg, FAILED_STATUS, null);
    }

    public static ResultModel exception(String msg) {
        return new ResultModel(msg, EXCEPTION_STATUS, null);
    }

    public static ResultModel fail(String msg, Integer errorCode) {
        return new ResultModel(msg, errorCode, null);
    }

    public static ResultModel fail(Iterable data) {
        return new ResultModel(MSG_FAILED_CONSTANT, FAILED_STATUS, data);
    }

    public static ResultModel fail(String msg, Iterable data) {
        return new ResultModel(msg, FAILED_STATUS, data);
    }

    public static ResultModel fail(String msg, Map data) {
        return new ResultModel(msg, FAILED_STATUS, data);
    }

    public static ResultModel fail(String msg, Integer errorCode, Object data) {
        return new ResultModel(msg, errorCode, data);
    }



    public ResultModel(String msg, Integer errorCode, Object data) {
//        if (data instanceof Map) {
//            optimizeMapAttrs((Map) data);
//        }
//        if (data instanceof Record) {
//            optimizeMapAttrs(((Record) data).getColumns());
//        }
//        if (data instanceof List) {
//            ((List) data).forEach(record -> {
//                if (record instanceof Record) {
//                    optimizeMapAttrs(((Record) record).getColumns());
//                }
//            });
//        }

        if(msg == null){
            data = "";
        }
        if(data instanceof String){
            String dataStr = data.toString();
            if(dataStr.contains(StrUtil.CRLF)){
                data = dataStr.replace(StrUtil.CRLF,  "<br>");
            }else
            if(dataStr.contains(StrUtil.LF)){
                data = dataStr.replace(StrUtil.LF,  "<br>");
            }else
            if(dataStr.contains(StrUtil.CR)){
                data = dataStr.replace(StrUtil.CR, " ");
            }
        }

        put(MSG, msg);
        put(ERROR_CODE, errorCode);
        put(DATA, data);
    }

    public int getErrorCode() {
        return Integer.parseInt(get(ERROR_CODE).toString());
    }

    public String getMsg() {
        Object o = get(MSG);
        if(null == o){
            return "";
        }
        return o.toString();
    }

    public Object getData() {
        return get(DATA);
    }

    public boolean success() {
        return getErrorCode() == SUCCESS_STATUS;
    }

    private static void optimizeMapAttrs(Map map) {
        if (map != null && !map.isEmpty()) {
            Iterator iter = map.entrySet().iterator();

            while (iter.hasNext()) {
                Entry entry = (Entry) iter.next();
                if (entry.getValue() == null) {
                    entry.setValue(new ArrayList<>());
                }
            }

        }
    }
}
